package org.gw.building.util;

import com.github.sommeri.less4j.LessCompiler;
import com.github.sommeri.less4j.LessCompiler.CompilationResult;
import com.github.sommeri.less4j.LessCompiler.Problem;
import com.github.sommeri.less4j.core.ThreadUnsafeLessCompiler;
import com.yahoo.platform.yui.compressor.CssCompressor;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.springframework.beans.factory.InitializingBean;

import java.io.File;
import java.io.FileWriter;
import java.io.StringReader;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LessCompilerWrapper implements InitializingBean {

	private String rootPath;
	private Map<String, String> lessFiles;
	private Logger log = Logger.getLogger(getClass().getName());

	public String getRootPath() {
		return rootPath;
	}

	public void setRootPath(String rootPath) {
		this.rootPath = rootPath;
	}

	public Map<String, String> getLessFiles() {
		return lessFiles;
	}

	public void setLessFiles(Map<String, String> lessFiles) {
		this.lessFiles = lessFiles;
	}

	public void afterPropertiesSet() throws Exception {
		if (lessFiles == null || lessFiles.keySet().size() == 0) {
			return;
		}
		if (rootPath == null) {
			rootPath = System.getProperty("train.root");
		}
		final File root = new File(rootPath);
		FileAlterationMonitor monitor = new FileAlterationMonitor(300);
		for (String less : lessFiles.keySet()) {
			final String outputFile = lessFiles.get(less);
			final File file = new File(root, less);
			compile(file, new File(root, outputFile));
			FileAlterationObserver observer = new FileAlterationObserver(file.getParentFile());
			observer.addListener(new FileAlterationListenerAdaptor() {
				@Override
				public void onFileChange(File f) {
					try {
						if (f.equals(new File(root, outputFile))) {
							return;
						}
						compile(file, new File(root, outputFile));
						System.out.println("less file changed");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
			monitor.addObserver(observer);
		}
		monitor.start();
	}

	private void compile(File file, File out) {
		FileWriter fileWriter = null;
		try {
			LessCompiler compiler = new ThreadUnsafeLessCompiler();
			CompilationResult compilationResult = compiler.compile(file);
			for (Problem warning : compilationResult.getWarnings()) {
				log.log(Level.WARNING, format(warning));
			}
			StringReader reader = new StringReader(compilationResult.getCss());
			CssCompressor compressor = new CssCompressor(reader);
			fileWriter = new FileWriter(out);
			compressor.compress(fileWriter, -1);
			fileWriter.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fileWriter.close();
			} catch (Exception e) {
			}
		}
	}

	private static String format(Problem warning) {
		return warning.getLine() + ":" + warning.getCharacter() + " " + warning.getMessage();
	}

}
